import * as THREE from 'three';

// 加载器  为场景添加模型
import { FBXLoader } from "three/examples/jsm/loaders/FBXLoader";


// Orbit controls（轨道控制器）可以使得相机围绕目标进行轨道运动
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'

/**
 * 为了真正能够让你的场景借助 three.js 来进行显示，
 * 需要以下几个对象：场景（scene）、相机（camera）和渲染器（renderer），
 * 就能透过摄像机渲染出场景。
 * */
const scene = new THREE.Scene();
// scene.background = new THREE.Color("#ccc"); //创建颜色对象
// scene.background = new THREE.Color(0xff00ff); //创建颜色对象
// scene.background = new THREE.Color("rgb(25,56,89)"); //创建颜色对象
// scene.background = new THREE.Color("hsl(45, 90%, 41%)"); //创建颜色对象

// 纹理贴图
const texture = new THREE.TextureLoader().load("/image/pandas.jpg")
// scene.background = texture
// scene.background = new THREE.Color('gray')
/**
 * PerspectiveCamera（透视摄像机）
 * 第一个参数是视野角度（FOV）
 *    视野角度就是无论在什么时候，你所能在显示器上看到的场景的范围，它的单位是角度(与弧度区分开)。
 * 第二个参数是长宽比（aspect ratio）
 *    用一个物体的宽除以它的高的值。比如说，当你在一个宽屏电视上播放老电影时，可以看到图像仿佛是被压扁的。
 * 接下来的两个参数是近截面（near）和远截面（far）
 *    当物体某些部分比摄像机的远截面远或者比近截面近的时候，该这些部分将不会被渲染到场景中。
 *    或许现在你不用担心这个值的影响，但未来为了获得更好的渲染性能，你将可以在你的应用程序里去设置它。
 */
const camera = new THREE.PerspectiveCamera( 75, 1.0 , 0.1, 1000 );
camera.position.set(-2, 34, 40);
camera.lookAt(0, 0, 0);
/**
 * 接下来是渲染器。
 *    在这里用到的 WebGLRenderer 渲染器之外，Three.js 同时提供了其他几种渲染器，当用户所使用的浏览器过于老旧，或者由于其他原因不支持 WebGL 时，可以使用这几种渲染器进行降级。
 */
const renderer = new THREE.WebGLRenderer({ 
	canvas: document.querySelector('#canvas'), //指定渲染的容器，不添加则会自动生成  也可以使用renderer.setSize(window.innerWidth, window.innerHeight);  自适应窗口大小  或者在window.onresize事件中重设renderer的大小  详见https://threejs.org/docs/#manual/en/introduction/How-to-use-threejs-with-web-pages  或者https://www.jian
	antialias: true //抗锯齿
}); 
renderer.shadowMap.enabled = true;

const ambientLight = new THREE.AmbientLight(0xffffff)
ambientLight.position.set(-60,160,40)
scene.add(ambientLight)

// const directionalLight = new THREE.DirectionalLight(0xffffff)
// directionalLight.position.set(-60,160,40)
// directionalLight.castShadow = true
// const directionalLightHelper = new THREE.DirectionalLightHelper(directionalLight, 0xffffff)
// scene.add(directionalLight)

const plane = new THREE.Mesh(
	new THREE.PlaneGeometry(100,100),
  new THREE.MeshStandardMaterial({
		color: 0xeeeeee
	})
)
plane.rotation.x = -Math.PI / 2
plane.receiveShadow = true
scene.add(plane)

const fbxLoader = new FBXLoader()
let mixer
fbxLoader.load(
	'./2.0/22-rp_manuel_animated_001_dancing_fbx/rp_manuel_animated_001_dancing.fbx',
	(fbx) => {
		console.log(fbx);
		const model = fbx
		fbx.castShadow = true
		fbx.scale.set(0.1,0.1,0.1)
		fbx.rotation.x = -Math.PI / 32

		mixer = new THREE.AnimationMixer(model)

		const animations = fbx.animations
		const dancingClip = animations.find(animation => animation.name === 'Take 001')
		if (dancingClip) {
			// 关键帧数据转为动作
			const action = mixer.clipAction(dancingClip)
			action.reset()
			action.play() // 动作播放
		}
		scene.add(model)
	},
	(process) => {
		// console.log(process);
		console.log(`${(process.loaded / process.total * 100).toFixed(2)}%`);
		
	},
	(error) => {
		console.log(error);
		
	}
)

//辅助观察的坐标系
const axesHelper = new THREE.AxesHelper(1000);
// 设置x,y,z轴的颜色
axesHelper.setColors(new THREE.Color(0xff0000), new THREE.Color(0x00ff00), new THREE.Color('pink'))
// scene.add(axesHelper);


// 控制器的使用
// 控制器实例化  参数：相机  绑定事件的元素
const controls = new OrbitControls( camera, renderer.domElement );

//controls.update() must be called after any manual changes to the camera's transform
controls.enableDamping = true //启用惯性


controls.addEventListener('change', () => {
  renderer.render( scene, camera )
  console.log(camera.position);
  
})

const clock = new THREE.Clock();
function animate(){
	const elapsedTime = clock.getDelta()
	controls.update();
	if(mixer) mixer.update(elapsedTime)
	requestAnimationFrame(animate);
  renderer.render(scene, camera);
}
animate()